home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
boot
/
czesc_2
/
snap
/
snapgfx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-09-13
|
11KB
|
475 lines
/*
* $VER:SnapGfx.c - (11.09.95) 17:39:11 Copyright © 1995 by Mikael Karlsson & Sylvain ROUGIER
*
* Created: 1988
* Modified: 11 Sep 1995 17:39:11
*
* Make>> smake
*
* 09/09/95:
* fix, to save 8bit per gun palette under V39+
*
* 10/09/95:
* Now Alloc dynamaicaly BitMap struct. (future usage of AllocBitMap())
*/
#include "Snap.h"
#include "proto/Misc.h"
#include "proto/GfxSnap.h"
IMPORT BOOL Kick36;
IMPORT struct GfxBase *GfxBase;
IMPORT struct SnapRsrc *SnapRsrc;
IMPORT struct Image DiskImage;
IMPORT struct Image ClipImage;
IMPORT struct Gadget DiskGad;
IMPORT struct Gadget ClipGad;
IMPORT struct Gadget VProp, HProp;
IMPORT struct PropInfo VInfo, HInfo;
IMPORT struct Image VImage, HImage;
IMPORT struct NewWindow Nw;
IMPORT UBYTE *WindowTitle;
IMPORT LONG xl; /* leftmost x position */
IMPORT LONG xr; /* rightmost x position */
IMPORT LONG yt; /* topmost y position */
IMPORT LONG yb; /* bottommost y position */
IMPORT LONG mx, my; /* Mouse position in pixels */
#define GfxFrame 4L
IMPORT Point OldFrame[ ];
IMPORT Point NewFrame[ ];
IMPORT LONG OFType; /* Old frame type: ShortFrame/LongFrame */
IMPORT UWORD Ptrn;
IMPORT WORD Pattern[ ];
IMPORT struct RastPort MyRP;
IMPORT struct BitMap MyBM;
IMPORT struct Screen *theScreen;
IMPORT struct RastPort rp;
IMPORT struct timerequest MyTR;
IMPORT LONGBITS cancelsignal, donesignal, movesignal;
IMPORT LONGBITS clicksignal, ticksignal, timersignal;
IMPORT WORD action;
LONG TopBar;
LONG LeftBar;
LONG RightBar;
LONG BottomBar;
LONG ScreenFontHeight;
struct TextFont *ScreenFont;
VOID FixHeights( )
{
struct Screen WBScreen;
OpenWorkBench( );
if ( GetScreenData( ( char *)&WBScreen, ( LONG) sizeof ( struct Screen), WBENCHSCREEN, NULL))
{
/* Now this is a good practice */
TopBar = WBScreen.WBorTop + WBScreen.RastPort.TxHeight + 1;
LeftBar = WBScreen.WBorLeft;
RightBar = WBScreen.WBorRight;
BottomBar = WBScreen.WBorBottom;
ScreenFont = WBScreen.RastPort.Font;
if ( !ScreenFont)
{
Forbid( );
ScreenFont = GfxBase->DefaultFont;
Permit( );
}
ScreenFontHeight = ScreenFont->tf_YSize;
}
else
{
/* Sorry, but I don't realise how this could fail.
Well, if we're snapping on another screen and
WB is closed and it can't be opened by GetScreenData( )...
Anyway, IF this should happen -- Use Topaz 8 */
TopBar = 10;
LeftBar = 2;
RightBar = 2;
BottomBar = 1;
ScreenFontHeight = 8;
Forbid( );
ScreenFont = GfxBase->DefaultFont;
Permit( );
}
}
struct GfxSnap *CreateGfxSnap( void)
{
struct GfxSnap *GfxSnap;
if ( GfxSnap = AllocVec( sizeof( struct GfxSnap), MEMF_ANY|MEMF_CLEAR))
{
return GfxSnap;
}
return NULL;
}
void DeleteGfxSnap( struct GfxSnap *GfxSnap)
{
if ( GfxSnap)
{
if ( GfxSnap->BitMap)
{
Snp_FreeBitMap( GfxSnap->BitMap, GfxSnap->width, GfxSnap->height);
}
FreeVec( GfxSnap);
}
return;
}
static void CopyColorDefs( ULONG Depth, struct ColorMap *ColorMap, UBYTE RGB8[][3])
{
ULONG i = Depth;
if ( SysBase->LibNode.lib_Version < 39)
{
ULONG col;
while ( i-- && ( col = GetRGB4( ColorMap, i)) != -1L)
{
RGB8[ i][ 0] = RGB4ToRR( col);
RGB8[ i][ 1] = RGB4ToGG( col);
RGB8[ i][ 2] = RGB4ToBB( col);
}
}
else
{
while ( i--)
{
ULONG RGB[ 3];
GetRGB32( ColorMap, i, 1, RGB);
RGB8[ i][ 0] = RGB32ToRGB8( RGB[ 0]);
RGB8[ i][ 1] = RGB32ToRGB8( RGB[ 1]);
RGB8[ i][ 2] = RGB32ToRGB8( RGB[ 2]);
}
}
}
/* SnapGfx is the actual graphics snapper.
** It steals the bitmap data from the given rastport
** and puts it in a separate bitmap.
** It also prepares the NewWindow structure according
** to the snapped bitmap.
** The coordinates are assumed to be valid.
*/
struct GfxSnap * SnapGfx( struct RastPort *rp)
{
struct GfxSnap *GS;
LONG i;
GS = CreateGfxSnap();
if ( !GS)
{
return NULL;
}
GS->x = xl;
GS->y = yt;
GS->width = xr - xl + 1;
GS->height = yb - yt + 1;
if ( xr < xl + MINWIDTH)
{ /* Can't have too small windows */
xr = xl + MINWIDTH;
}
if ( yb < yt + MINHEIGHT)
{
yb = yt + MINHEIGHT;
}
GS->depth = rp->BitMap->Depth;
GS->viewmode = theScreen->ViewPort.Modes;
GS->pagew = theScreen->Width;
GS->pageh = theScreen->Height;
i = ( GS->viewmode & HAM ? 16 : 1L << GS->depth);
/* Copy the color map in case we should need it later */
CopyColorDefs(
GS->viewmode & HAM ?
16 :
1L << GS->depth,
theScreen->ViewPort.ColorMap,
GS->rgb);
/* Set up a nice bitmap */
InitRastPort( &MyRP);
MyRP.BitMap = GS->BitMap = AllocBitMap( GS->width, GS->height, GS->depth, BMF_DISPLAYABLE, rp->BitMap);
if ( !GS->BitMap)
{
DeleteGfxSnap( GS);
return NULL;
}
/* Copy the selected part of the screen */
ClipBlit( rp, xl, yt, &MyRP, 0L, 0L, GS->width, GS->height, 0xC0L);
if ( !Kick36)
{
VInfo.Flags |= PROPBORDERLESS;
HInfo.Flags |= PROPBORDERLESS;
}
CopyMem( ( char *)&DiskGad, ( char *)&GS->DiskGad, ( LONG) sizeof ( DiskGad) + sizeof ( ClipGad) + sizeof ( VProp) + sizeof ( HProp) + sizeof ( VInfo) + sizeof ( HInfo) + sizeof ( VImage) + sizeof ( HImage));
GS->topbar = TopBar;
GS->leftbar = LeftBar;
GS->rightbar = 18; /* ( Kick36 ? RightBar : 18); */
GS->bottombar = 10;
Nw.LeftEdge = xl;
Nw.TopEdge = yt;
Nw.Width = xr - xl + 1 + GS->leftbar + GS->rightbar;
Nw.Height = yb - yt + 1 + GS->topbar + GS->bottombar;
Nw.Flags &= ~( SIMPLE_REFRESH | SMART_REFRESH | NOCAREREFRESH);
Nw.Flags |= ( SnapRsrc->flags & SIMPLEREFRESH ?
SIMPLE_REFRESH :
SMART_REFRESH | NOCAREREFRESH);
Nw.Title = WindowTitle;
Nw.MinWidth = MINWIDTH + 1 + GS->leftbar + GS->rightbar;
Nw.MinHeight = MINHEIGHT + 1 + GS->topbar + GS->bottombar;
Nw.MaxWidth = Nw.Width;
Nw.MaxHeight = Nw.Height;
if ( Kick36)
Nw.Flags |= SIZEBBOTTOM | SIZEBRIGHT;
return GS;
}
VOID ExtendGfx( )
{
/* Fix which row we're talking about */
if ( my - yt < yb - my)
{ /* Find closest row */
yt = my; /* change top row */
}
else
{
yb = my; /* change bottom row */
}
if ( mx - xl < xr - mx)
{
xl = mx;
}
else
{
xr = mx;
}
}
VOID gfx_frame( )
{
NewFrame[ 0].x = xl;
NewFrame[ 0].y = yt;
NewFrame[ 1].x = xr;
NewFrame[ 1].y = yt;
NewFrame[ 2].x = xr;
NewFrame[ 2].y = yb;
NewFrame[ 3].x = xl;
NewFrame[ 3].y = yb;
NewFrame[ 4].x = xl;
NewFrame[ 4].y = yt;
draw_frame( GfxFrame);
}
WORD HandleGfx( void)
{
struct Layer_Info *LockedLayerInfo;
theScreen = WhichScreen( ); /* Find out where we are */
if ( !theScreen)
{ /* Don't know? Forget it. */
action = noaction;
return 0;
}
/* Lock everything - find out what happens */
LockedLayerInfo = &theScreen->LayerInfo;
// LockLayers( LockedLayerInfo);
/* Get a copy. Don't mess with somebody else's RP. */
CopyMem( ( char *)&theScreen->RastPort, ( char *)&rp, ( long)sizeof ( struct RastPort));
SetDrMd( &rp, COMPLEMENT);
xl = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
if ( xl < 0)
{
xl = 0;
}
if ( xl >= theScreen->Width)
{ /* Check those corners. Check those corners. */
xl = theScreen->Width - 1;
}
yt = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
if ( yt < 0)
{
yt = 0;
}
if ( yt >= theScreen->Height)
{
yt = theScreen->Height - 1;
}
xr = xl;
yb = yt;
Ptrn = ( SnapRsrc->CrawlPtrn ? SnapRsrc->CrawlPtrn : Pattern[ UNIT_FRAME]);
OFType = 0L;
gfx_frame( );
FOREVER
{
REGISTER LONGBITS sig;
MyTR.tr_time.tv_secs = 0;
MyTR.tr_time.tv_micro = 500000;
MyTR.tr_node.io_Command = TR_ADDREQUEST;
SendIO( ( struct IORequest *)&MyTR);
sig = Wait( movesignal | clicksignal | cancelsignal | donesignal | ticksignal | timersignal);
if ( CheckIO( ( struct IORequest *)&MyTR))
{
WaitIO( ( struct IORequest *)&MyTR);
erase_frame( );
// UnlockLayers( LockedLayerInfo); /* Unlock things */
sig = Wait( ticksignal); /* Wait for input handler to become avtive */
// LockLayers( LockedLayerInfo); /* Re-lock */
/* I guess I should check to see that the window is still
there. Aw, what the heck. Apologies to anyone who gets
bitten by this. */
DisplayBeep( NULL);
gfx_frame( );
}
else
{
AbortIO( ( struct IORequest *)&MyTR);
WaitIO( ( struct IORequest *)&MyTR);
SetSignal( 0, timersignal);
}
if ( ( sig & ticksignal) && ( SnapRsrc->CrawlPtrn != 0xffff))
{
crawl_frame( 1L);
}
if ( sig & movesignal || sig & clicksignal)
{
mx = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
if ( mx < 0)
{
mx = 0;
}
if ( mx >= theScreen->Width)
{
mx = theScreen->Width - 1;
}
my = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
if ( my < 0)
{
my = 0;
}
if ( my >= theScreen->Height)
{
my = theScreen->Height - 1;
}
ExtendGfx( );
gfx_frame( );
}
if ( sig & cancelsignal)
{ /* Cancelled? */
erase_frame( );
// UnlockLayers( LockedLayerInfo);
return 0;
}
if ( sig & donesignal)
{ /* Finished. Copy gfx. */
struct GfxSnap *GS;
erase_frame( );
if ( xl == xr || yt == yb)
{
action = noaction;
// UnlockLayers( LockedLayerInfo);
return 0;
}
if ( xr >= theScreen->Width)
{
xl -= xr - theScreen->Width - 1;
xr = theScreen->Width - 1;
}
if ( yb >= theScreen->Height)
{
yt -= yb - theScreen->Height - 1;
yb = theScreen->Height - 1;
}
FixHeights( );
GS = SnapGfx( &rp); /* Snap! */
// UnlockLayers( LockedLayerInfo);
if ( GS)
{
if ( GS->window = opensharedwindow( &Nw))
{
if ( SnapRsrc->flags & SIMPLEREFRESH)
{
ModifyIDCMP( GS->window,
GS->window->IDCMPFlags | REFRESHWINDOW);
}
if ( Kick36)
{
GS->topbar = GS->window->BorderTop;
GS->leftbar = GS->window->BorderLeft;
GS->rightbar = GS->window->BorderRight;
GS->bottombar = 10; /*GS->window->BorderBottom; */
GS->HProp.TopEdge = -7;
GS->HProp.Height = 6;
}
GS->DiskGad.TopEdge = GS->topbar;
GS->DiskGad.LeftEdge = ( Kick36 ? -17 : -14);
GS->DiskGad.Width = ( Kick36 ? 18 : 14);
GS->ClipGad.TopEdge = GS->DiskGad.TopEdge + 12;
GS->ClipGad.LeftEdge = ( Kick36 ? -17 : -14);
GS->ClipGad.Width = ( Kick36 ? 18 : 14);
GS->HProp.GadgetRender = ( APTR) & GS->HImage;
GS->HProp.SpecialInfo = ( APTR) & GS->HInfo;
GS->VProp.TopEdge =
GS->ClipGad.TopEdge + ( Kick36 ? 14 : 15);
GS->VProp.LeftEdge = ( Kick36 ? 5 : 7) - GS->rightbar;
GS->VProp.Width = GS->rightbar - ( Kick36 ? 8 : 10);
GS->VProp.Height =
( Kick36 ? -28 : -27) - GS->bottombar - GS->topbar;
GS->VProp.GadgetRender = ( APTR) & GS->VImage;
GS->VProp.SpecialInfo = ( APTR) & GS->VInfo;
GS->DiskGad.NextGadget = &GS->ClipGad;
GS->ClipGad.NextGadget = &GS->VProp;
GS->VProp.NextGadget = &GS->HProp;
GS->HProp.NextGadget = NULL;
AddGList( GS->window, &GS->DiskGad, -1, -1, NULL);
GS->window->UserData = ( BYTE *) GS;
/* Put gfx in our new window */
AdjustSize( GS);
}
else
{
DeleteGfxSnap( GS);
}
}
else
{ /* Good question */
}
action = noaction;
return 0;
}
}
}